import moment from "moment";

import { plantInfoList, plantOrderList } from "./plant";

import { getTargetDateSignInReward } from "./signIn";

import { levelName, levelList } from "./level";

import { itemList } from "./item";

import { calc } from "a-calc";

const getDefaultUserInfo = () => {
    return {
        signInTimes: 0, // 累计签到天数
        targetDateIsSignIn: false, // 今天是否已签到
        sunTotal: 0, // 阳光总数
        sun: 50, // 可收获阳光
        maxSun: 100, // 最大积累阳光
        money: 100, // 钱
        level: 1, // 等级 即levelList的index + 1
        exp: 0, // 当前等级经验
        allExp: 0, // 总经验
        // 阳光掉落频率 默认5分钟一次
        sunDropRate: 5,
        // 阳光掉落量 默认5
        sunDropAmount: 5,
        // 植物上限
        maxPlants: 10,
        // 商店刷新时间 默认12小时
        shopRefreshTime: 12,
        // 商店刷新价格 默认20
        shopRefreshPrice: 20,
        // 下次阳光掉落时间
        nextSunDropTime: moment().add(5, 'minutes').format('YYYY-MM-DD HH:mm'),
        // 保护结束时间
        protectEndTime: moment().add(24, 'hours').format('YYYY-MM-DD HH:mm'), // 不存在保护时 为空
        // 是否正在战斗
        isBattling: false,
    }
}


let defaultUserLog = {
    plantLog: [], // 植物相关日志
    moneyLog: [], // 购买相关日志
    sunLog: [], // 收获阳光日志
}

let deletePlantTypeList = { // 铲除同名植物的执行策略
    'auto': '按种植时间先后铲除',
    'hp': '优先铲除当前血量较低的',
    'level': '优先铲除等级较低的',
}

let defendConfig = { // 防御策略
    'auto': '自动',
    'distance': '优先攻击最近的目标',
    'hph': '优先攻击血量较高的目标',
    'hpl': '优先攻击血量较低的目标',
    'not': '不进行防守',
}

let defaultUserConfig = {
    deletePlantType: 'auto', // 铲除同名植物的执行策略
    defendConfig: 'auto', // 防御策略
}

// 用户默认 扩建
let defaultUserExtension = {
    extensionNumber: 0, // 已扩展数量
    usedExtension: [], // 已购买的 不可重复购买的扩建的id
}

// 用户默认 装备
let defaultUserEquipment = {
    shovel: { // 铲子
        itemId: 0, // 装备的itemId
        info: {}, // 装备信息
    },
    plantBook: { // 植物图鉴 可在商店购买
        has: false, // 是否拥有植物图鉴
        level: 1, // 等级
    },
    botany: { // 植物学 可在商店购买
        has: false, // 是否拥有植物学
        level: 1, // 等级
    },
    sunReservoir: {
        itemId: 0, // 装备的itemId
        info: {}, // 装备信息
    },
    wateringCan: { // 浇水壶 暂未实装
        itemId: 0, // 装备的itemId
        info: {}, // 装备信息
    },
    fertilizer: { // 肥料 暂未实装
        itemId: 0, // 装备的itemId
        info: {}, // 装备信息
    }
}

export function generateChineseNumber(number) {
    const chineseNumbers = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
    const chineseUnits = ['', '十', '百', '千', '万'];

    if (number <= 10) {
        return chineseNumbers[number];
    } else {
        const numberString = number.toString();
        let result = '';
        
        for (let i = 0; i < numberString.length; i++) {
        const digit = parseInt(numberString[i]);
        
        if (digit !== 0) {
            if (numberString.length === 2 && i === 0 && digit === 1) {
            result += chineseUnits[numberString.length - i - 1];
            } else {
            result += chineseNumbers[digit] + chineseUnits[numberString.length - i - 1];
            }
        } else {
            if (i === 0 || numberString[i - 1] !== '0') {
            result += chineseNumbers[digit];
            }
        }
        }
        
        return result;
    }
}

let chineseNumberToNumber = (chineseNumber) => {
    const chineseNumbers = ['', '一', ['二', '两'], '三', '四', '五', '六', '七', '八', '九', '十'];
    const chineseUnits = ['', '十', '百', '千', '万'];
    
    let result = 0;
    let unit = 1;
    
    for (let i = chineseNumber.length - 1; i >= 0; i--) {
        const char = chineseNumber[i];
        if (char == '十') {
            unit *= 10;
            if (chineseNumber.length == 1) result = 10 // '十' 单独出现时为 10
        } else if (char == '百') {
            unit *= 100;
        } else if (char == '千') {
            unit *= 1000;
        } else if (char == '万') {
            unit *= 10000;
        } else {
            let number = 0
            chineseNumbers.map((i, index) => {
                if (typeof i === 'object') {
                    if (i.indexOf(char) != -1) {
                        number = index;
                    }
                } 
                else {
                    if (i == char) {
                        number = index;
                    }
                }
            })
            result += number * unit;
            unit = 1;
        }
    }

    return result;
}

const simpleOrderList = { // 简易指令
    'plant': ['plant', 'p', '植物', '我的植物'],
    'plantInfo': ['plantInfo', 'pinfo', '植物信息', '植物类型'],
    'info': ['info', '信息', '我的信息', '我'],
    'harvest': ['sun', 'harvest', 'harvestSun', '收获', '收', '收阳光'],
    'shop': ['shop', 's', '商店', '购买道具', '商品'],
    'allShop': ['allshop', '商店 显示隐藏', '全部商店', '全部商品', '商店 显示全部', '商店 全部', '商品 全部'],
    'sign': ['sign', '签到', '打卡'],
    'items': ['i', 'items', 'item', '道具', '背包', '我的背包', '我的道具'],
    'equip': ['equip', 'e', '装备', '我的装备'],
    'level': ['level', 'lv', '等级', '我的等级', '花园等级', '我的花园等级'],
    'task': ['task', 't', '任务', '我的任务', '任务列表'],
    'log': ['log', 'l', '日志', '我的日志', '我的记录', '我的记录日志'],
    'sunLog': ['sunlog', 'sunl', 'sl', '阳光日志', '阳光记录', 'slog'],
    'moneyLog': ['moneyLog', 'moneyl', 'mlog', '金钱日志', '金钱记录', 'ml'],
    'plantLog': ['plantLog', 'plantl', 'plog', '植物日志', '植物记录', 'pl'],
    'resetLog': ['resetLog', 'resetl', 'rl', '重置日志', '清空日志', 'resetlog', 'rlog'],
    'weather': ['weather', 'w', '天气', '当前天气', '天'],
    'strategy': ['strategy', '策略', '战略', '我的策略', '我的战略'],
    'fakeBattle': ['f', 'fake', 'fakeBattle', 'moni', '模拟', '模拟对战', '测试', 'test'],
    'help': ['help', 'h', '帮助', '花园帮助'],
    'ranking': ['ranking', 'rank', 'r', '排行榜', '排行', '排名'],
    'orderHelp': ['orderhelp', 'oh', '指令', '指令帮助', '所有指令'],
    'tombstone': ['tombstone', '墓碑', '墓', '碑'],
    'wakeup': ['wakeup', '唤醒', '唤醒僵尸', '召唤僵尸', 'wake'],
    'trial': ['试炼', '升级'],
    'book': ['book', 'b', '图鉴', '图'],
    'getImage': ['随机图片', '图片']
}

const totalPlant = (plantList = [], data, extensionNumber) => { // 统计并陈列植物
    if (plantList && plantList.length) {
        let result = '你在后花园种了：\n'
        // 分类
        let plantType = {}
        for (let i = 0; i < plantList.length; i++) {
            let plantName = plantList[i].name
            if (plantType[plantName]) {
                plantType[plantName].number += 1
            } else {
                plantType[plantName] = plantList[i]
                plantType[plantName].number = 1
            }
        }
        // 统计
        for (let i = 0; i < Object.keys(plantType).length; i++) {
            let plantName = Object.keys(plantType)[i]
            result += `${plantName}：${plantType[plantName].number}个\n`
        }
        result += `种植上限：${plantList.length} / ${data.maxPlants + extensionNumber}\n`
        if (extensionNumber) result += `花园扩建：当前额外种植上限+${extensionNumber}\n`
        result += `Tip：升级和购买相应道具可提高种植上限`
        return result
    }
    else return '你的后花园空空的，快去种点植物吧'
}

// 分钟转时分
const minuteToHM = (minute) => {
    let hour = Math.floor(minute / 60)
    let min = minute % 60
    return `${hour}小时${min}分钟`
}

// 计算用户当前阳光数量(每分钟触发)
const userHarvestSunCallback = (userData, weather, plantList = [], equipment = defaultUserEquipment) => {
    let { nextSunDropTime, sun, maxSun, sunDropRate, sunDropAmount } = userData
    if (equipment.sunReservoir.itemId) maxSun = maxSun * equipment.sunReservoir.info.value // 存在阳光储存器
    if (weather.sunDropAmountBuff != 1) sunDropAmount = Math.floor(sunDropAmount * weather.sunDropAmountBuff)
    if (weather.sunDropRateBuff != 1) sunDropRate = calc(`${sunDropRate} * (1 / ${weather.sunDropRateBuff}) | <=2`)
    nextSunDropTime = moment(nextSunDropTime, 'YYYY-MM-DD HH:mm')
    // 计算当前时间与下次阳光掉落时间的时间差
    let diffTime = nextSunDropTime.diff(moment(), 'minutes')
    if (diffTime == 0) {
        userData = userHarvestMoneyCallback(userData, plantList)
        // 当前为收获时间
        sun = sun + sunDropAmount
        if (sun > maxSun) sun = maxSun
        // 更新下次掉落时间
        nextSunDropTime = nextSunDropTime.add(sunDropRate, 'minutes').format('YYYY-MM-DD HH:mm')
        // 更新数据
        userData.sun = sun
        userData.nextSunDropTime = nextSunDropTime
        userData.isChanged = true
    }
    else if (diffTime < 0) {
        userData = userHarvestMoneyCallback(userData, plantList)
        diffTime = diffTime * -1
        // 在经过的时间内 一共掉落了几次阳光
        let sunDropTimes = Math.floor(diffTime / sunDropRate) + 1
        // 计算掉落量
        let sunDropAmounts = sunDropAmount * sunDropTimes
        sun = sun + sunDropAmounts
        if (sun > maxSun) sun = maxSun
        // 更新下次掉落时间
        nextSunDropTime = nextSunDropTime.add(sunDropRate, 'minutes').format('YYYY-MM-DD HH:mm')
        // 更新数据
        userData.sun = sun
        userData.nextSunDropTime = nextSunDropTime
        userData.isChanged = true
    }
    return userData
}

// 计算用户当前金币数量(每分钟触发 金盏花等铲除金钱的植物独有)
const userHarvestMoneyCallback = (userData, plantList = []) => {
    let { money, nextSunDropTime, sunDropRate } = userData
    nextSunDropTime = moment(nextSunDropTime, 'YYYY-MM-DD HH:mm')
    let diffTime = nextSunDropTime.diff(moment(), 'minutes')
    let moneyPlantList = plantList.filter(i => i.type == 1 && i.money && i.moneyProbability) // 生产植物 且 可生产金币
    let addMoney = 0
    if (diffTime == 0) {
        moneyPlantList.forEach(plant => {
            let hasHarvestMoney = Math.random() > (1 - plant.moneyProbability) // 是否产出金币
            if (hasHarvestMoney) {
                money = money + plant.money
                addMoney += plant.money
            }
        })
        userData.money = money
        userData.isChanged = true
        userData.isChangedMoney = true
    }
    else if (diffTime < 0) {
        diffTime = diffTime * -1
        // 在经过的时间内 一共掉落了几次阳光
        let sunDropTimes = Math.floor(diffTime / sunDropRate) + 1
        moneyPlantList.forEach(plant => {
            for (let index = 0; index < sunDropTimes; index++) {
                let hasHarvestMoney = Math.random() > (1 - plant.moneyProbability) // 是否产出金币
                if (hasHarvestMoney) {
                    money = money + plant.money
                    addMoney += plant.money
                }
            }
        })
        userData.money = money
        userData.isChanged = true
        userData.isChangedMoney = true
    }
    if (addMoney) userData.addMoney = addMoney
    return userData
}

// 计算目标用户当前阳光生产效率
const calcTargetUserSunDropAmount = (userData, plantList = []) => {
    let isDay = moment().hour() < 18 && moment().hour() > 6 // 当前是否为白天
    let plantSunDropAmount = plantList.filter(i => i.type == 1 && !(i.sleep && isDay)).reduce((sum, plant) => {
        return sum + plant.sun
    }, 0)
    userData.sunDropAmount = plantSunDropAmount + 5 // 植物生产效率 + 初始5生产频率
    return userData
}

const getsSunFullNeedTimeStr = (userData, targetWeather, equipment = defaultUserEquipment) => {
    let result = ''
    let { sun, maxSun, nextSunDropTime, sunDropAmount, sunDropRate } = userData
    // 天气buff
    if (targetWeather.sunDropAmountBuff != 1) {
        sunDropAmount = Math.floor(sunDropAmount * targetWeather.sunDropAmountBuff)
    }
    if (targetWeather.sunDropRateBuff != 1) {
        sunDropRate = calc(`${sunDropRate} * (1 / ${targetWeather.sunDropRateBuff}) | <=2`)
    }
    if (equipment.sunReservoir.itemId) { // 存在阳光储存器
        maxSun = maxSun * equipment.sunReservoir.info.value
    }
    if (sun >= maxSun) return result
    else {
        result += `\n距离阳光收集达到上限还要：`
        if (sunDropRate <= 0 || sunDropAmount <= 0) {
            result += `非常久`
        }
        else {
            nextSunDropTime = moment(nextSunDropTime, 'YYYY-MM-DD HH:mm')
            // 计算当前时间与下次阳光掉落时间的时间差
            let diffTime = nextSunDropTime.diff(moment(), 'minute', true)
            diffTime = Math.ceil(diffTime)
            // 下次收获阳光后 距离阳光达到上限需要的阳光
            let needSun = maxSun - sun
            // 需要掉落几次
            let needTimes = Math.floor(needSun / sunDropAmount)
            // 需要掉落的时间
            let needTime = calc(`${needTimes} * ${sunDropRate} | =0`)
            needTime = Number(needTime)
            needTime = needTime + diffTime
            let sunFullNeedTime = minuteToHM(needTime)
            result += sunFullNeedTime
        }
        return result
    }
}

// 用户签到回调
const UserSignInCallback = (userData, items = []) => {
    let { signInTimes } = userData
    let signInRewardStr = ''
    let signInReward = getTargetDateSignInReward(signInTimes)
    signInReward.map(i => {
        let { id, num } = i
        let itemInfo = itemList.find(j => j.id == id)
        let hasItem = items.findIndex(j => j.id == id)
        if (hasItem > -1) {
            items[hasItem].num += num
        }
        else {
            items.push({
                id,
                num,
                info: itemInfo
            })
        }
        signInRewardStr += `\n ⭐ ${itemInfo.name} * ${num}`
    })
    // console.log('签到成功 items', items);
    userData.signInTimes = signInTimes + 1
    userData.targetDateIsSignIn = true
    let msg = `签到成功喵~ 记得明天也要签到哦\n已累计签到${userData.signInTimes}天\n以下奖励已进入背包:\n使用指令「 item 」查看背包` + signInRewardStr
    return {
        userData,
        items,
        msg
    }
}

// 铲除植物回调
const deletePlantCallback = (plantList, userConfig = {}, deleteNumber, deletePlantId) => {
    // 根据当前用户铲除植物策略进行铲除植物
    let result = [...plantList]
    let { deletePlantType = 'auto' } = userConfig
    if (deletePlantType == 'auto') { // 铲除策略: 随机铲除
        for (let index = 0; index < deleteNumber; index++) {
            let deleteIndex = result.findIndex(i => i.id == deletePlantId)
            result.splice(deleteIndex, 1)
        }
    }
    else if (deletePlantType == 'hp') { // 铲除策略: 铲除血量最低植物
        let firstIndex = result.findIndex(i => i.id == deletePlantId)
        for (let i = 0; i < deleteNumber; i++) {
            let deleteIndex = result.reduce((minIndex, plant, index) => {
                if (plant.hp < result[minIndex].hp && plant.id == deletePlantId) {
                    return index
                }
                else {
                    return minIndex
                }
            }, firstIndex)
            result.splice(deleteIndex, 1)
        }
    }
    else if (deletePlantType == 'level') { // 铲除策略: 铲除阳光最低植物 
        let firstIndex = result.findIndex(i => i.id == deletePlantId)
        for (let index = 0; index < deleteNumber; index++) {
            let deleteIndex = result.reduce((minIndex, plant, index) => {
                if (plant.level < result[minIndex].level && plant.id == deletePlantId) {
                    return index
                }
                else {
                    return minIndex
                }
            }, firstIndex)
            result.splice(deleteIndex, 1)
        }
    }
    return result
}

// 庇护时长计算
const protectDurationCalc = (lossSun = 0, lossPlant, isPlayer = false) => {
    let list = Object.values(plantInfoList)
    let lossPlantPrice = lossPlant.reduce((sum, plant) => {
        let item = list.find(i => i.id == plant.id)
        return sum + item.price * plant.num
    }, 0)
    let res = 0
    res += lossSun + lossPlantPrice
    if (!isPlayer) res += 50
    let protectEndTime = ''
    let duration = 0
    if (res > 0) {
        duration = calc(`${res} / 5 * 3 | <=2`)
        // 庇护时间计算 每损失5阳光值 庇护时间+3分钟 非玩家发起的战斗 默认30分钟庇护时间打底
        protectEndTime = moment().add(duration, 'minutes').format('YYYY-MM-DD HH:mm:ss')
    }
    return {
        protectEndTime,
        protectDuration: duration,
    }
}

export {
    getDefaultUserInfo,
    defaultUserLog,
    defaultUserConfig,
    defaultUserExtension,
    defaultUserEquipment,
    simpleOrderList,
    levelName,
    levelList,
    plantOrderList,
    plantInfoList,
    deletePlantTypeList,
    defendConfig,
    totalPlant,
    chineseNumberToNumber,
    minuteToHM,
    userHarvestSunCallback,
    calcTargetUserSunDropAmount,
    getsSunFullNeedTimeStr,
    UserSignInCallback,
    deletePlantCallback,
    protectDurationCalc,
}